package model

import (
	"encoding/base64"
	"ginblog/utils/errmsg"
	"golang.org/x/crypto/scrypt"
	"gorm.io/gorm"
	"log"
)

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20);not null" json:"username" comment:"账号"`
	Password string `gorm:"type:varchar(200);not null" json:"password" comment:"密码"`
	Rule     int    `gorm:"type:int;DEFAULT:2" json:"rule"  comment:"角色"`
}

// CheckUser 检查用户
func CheckUser(name string) (code int) {
	var user User
	db.Select("id").Where("username=?", name).First(&user)
	if user.ID > 0 {
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SUCCSE
}

// CreatUser 创建用户
func CreatUser(data *User) int {
	data.Password = ScryptPw(data.Password)
	err := db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

// GetUser 获取用户及分页
func GetUser(pageSize int, pageNum int) []User {

	var users []User
	err = db.Limit(pageSize).Offset((pageNum - 1) * pageSize).Find(&users).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil
	}
	return users
}

func UpdateCheckUser(id int, name string) (code int) {
	var user User
	db.Select("id").Where("username=?", name).First(&user)
	if user.ID > 0 && int(user.ID) != id {
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SUCCSE
}

// DelUser 删除用户
func DelUser(id int) int {
	var user User
	db.Select("id").Where("id=?", id).First(&user)
	if user.ID >= 1 {
		db.Where("id = ?", id).Delete(&user)
		return errmsg.SUCCSE
	}
	return errmsg.ERROR_USER_NOT_EXIST
}

// EdtUser 修改用户
func EdtUser(id int, data *User) int {
	var user User

	var maps = make(map[string]interface{})
	maps["username"] = data.Username
	maps["rule"] = data.Rule
	errs := db.Model(&user).Where("id=?", id).Updates(maps).Error
	if errs != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

func CheckLogin(username string, password string) (User, int) {
	var user User
	db.Where("username=?", username).First(&user)
	if user.ID == 0 {
		return user, errmsg.ERROR_USER_NOT_EXIST
	}
	if user.Password != ScryptPw(password) {
		return user, errmsg.ERROR_PASSWORD_WRONG
	}
	if user.Rule != 1 {
		return user, errmsg.ERROR_USER_NO_RIGHT
	}
	return user, errmsg.SUCCSE
}

// BeforeSave gorm钩子，这里指向同一个结构体不需要返回，而且不需要要调用，框架自己调用
func (data *User) BeforeSave() {
	data.Password = ScryptPw(data.Password)
}

// ScryptPw 加密
func ScryptPw(password string) string {
	const KenLen = 10
	salt := make([]byte, 8)
	salt = []byte{11, 22, 33, 55, 66, 77, 88, 99}
	HashPw, err := scrypt.Key([]byte(password), salt, 1024, 8, 1, KenLen)
	if err != nil {
		log.Fatal(err)
	}
	fpw := base64.StdEncoding.EncodeToString(HashPw)
	return fpw
}
